home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / demo3.zoo / demo / misc / close.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-24  |  6.4 KB  |  281 lines

  1. /*                        Copyright (c) 1987 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: close.c,v 4.6 88/08/08 09:43:38 sau Exp $
  9.     $Source: /tmp/mgrsrc/demo/misc/RCS/close.c,v $
  10. */
  11. static char    RCSid_[] = "$Source: /tmp/mgrsrc/demo/misc/RCS/close.c,v $$Revision: 4.6 $";
  12.  
  13. /* close a window  - keep icon uncovered */
  14.  
  15. #include <signal.h>
  16. #include "term.h"
  17.  
  18.  
  19. static int debug = 0;            /* for debugging */
  20.  
  21. static int wide, high, xmax, ymax, border;    /* global mgr state info */
  22.  
  23. #define Max(x,y)    ((x)>(y)?(x):(y))
  24. #define Min(x,y)    ((x)<(y)?(x):(y))
  25. #define dprintf        if (debug) fprintf
  26.  
  27. #define XSLOP        6    /* extra horizontal space around window */
  28. #define YSLOP        2    /* extra vertical space around window */
  29. #define WAIT        20    /* seconds until next look for an opening */
  30. #define RAND        11    /* max time to wait before moving */
  31.  
  32. #define Active        "A\r"
  33. #define Covered        "C\r"
  34. #define Redraw        "R\r"
  35.  
  36.  
  37. main(argc,argv)
  38. int argc;
  39. char **argv;
  40.    {
  41.    char host[16];            /* host name */
  42.    char line[MAXLINE];            /* input buffer for events */
  43.    char text[MAXLINE];            /* text for icon */
  44.    char moving[MAXLINE];        /* text for icon while moving */
  45.    int font;
  46.    int clean();
  47.    int sigalrm();
  48.    char *getenv();
  49.  
  50.    ckmgrterm( *argv );
  51.  
  52.    /* turn on debugging */
  53.  
  54.    if (getenv("DEBUG"))
  55.       debug++;
  56.  
  57.    /* get icon text */
  58.  
  59.    srand(getpid());
  60.    if (debug)
  61.       setbuf(stderr,NULL);
  62.    m_setup(M_FLUSH);
  63.    m_push(P_ALL & (~P_MOUSE));    
  64.  
  65.    signal(SIGINT,clean);
  66.    signal(SIGTERM,clean);
  67.    signal(SIGALRM,sigalrm);
  68.  
  69.    m_ttyset();
  70.  
  71.    if (argc>3)
  72.       usage(*argv);
  73.  
  74.    if (argc>1  &&  *argv[1] ) {
  75.       /* There is a message and it is not zero length */
  76.       text[0] = '\f';
  77.       /* If the string in argv[1] contains a %d, then the window set ID will
  78.          be included in the message.
  79.       */
  80.       sprintf(&text[1], argv[1], m_setid());
  81.       sprintf(moving, "\fMoving %s", &text[1]);
  82.    }
  83.    else {
  84.       /* No message or it is zero length. */
  85.       gethostname(host,sizeof(host));
  86.       sprintf(text, "\f%s(%d)", host, m_setid());
  87.       sprintf(moving, "\fMoving(%d)", m_setid());
  88.       }
  89.  
  90.    if (!debug)
  91.       m_setmode(M_NOINPUT);
  92.    if (argc==3  &&  (font=atoi(argv[2])) > 0)
  93.       m_font(font);
  94.  
  95.    setupwindow(text);
  96.  
  97.    /* set events */
  98.  
  99.    m_setevent(ACTIVATED,Active);
  100.    m_setevent(COVERED,Covered); 
  101.    m_setevent(REDRAW,Redraw); 
  102.  
  103.    /* bury it and wait */
  104.  
  105.    if (!goto_spot(wide,high)) {
  106.       /* Window was too big; use font zero and try again */
  107.       m_font( 0 );
  108.       setupwindow( text );
  109.       }
  110.    goto_spot(wide,high);
  111.        /* no place to go; we'll stay where we are until something opens up */
  112.  
  113.    while(1) {
  114.       m_clearmode(M_ACTIVATE);
  115.       if (!debug)
  116.          m_setmode(M_NOINPUT);
  117.       m_gets(line);
  118.       alarm(0);
  119.       m_push(P_EVENT);
  120.       m_setevent(COVERED,Covered); 
  121.       dprintf(stderr,"Read [%s]\n",line);
  122.  
  123.       if (*line == *Active)            /* activate window */
  124.          clean();
  125.  
  126.       else if (*line == *Covered) {
  127.          m_printstr(moving);
  128.          get_size(0,0,&wide,&high);
  129.          wide += 2*border+XSLOP;
  130.          high += 2*border+YSLOP;
  131.          dprintf(stderr,"going to ?,? %d %d\n",wide,high);
  132.          sleep(((unsigned)rand()) % RAND);
  133.          if (goto_spot(wide,high)) {
  134.         m_clearevent(COVERED);
  135.             m_clearmode(M_ACTIVATE);
  136.             }
  137.          else {                /* no place to go */
  138.             alarm(WAIT);
  139.             }
  140.          }
  141.       m_printstr(text);
  142.       m_pop();
  143.       }
  144.    }
  145.  
  146. /* restore window state and exit */
  147.  
  148. static
  149. clean()
  150.    {
  151.    m_ttyreset();
  152.    m_popall();
  153.    exit(1);
  154.    }
  155.  
  156. /* find an unused spot for a window */
  157.  
  158. static
  159. int
  160. goto_spot(wide, high)
  161. int wide,high;                    /* minimum spot size */
  162.    {
  163.    struct window_data    coords[1000];    /* present window coords. go here */
  164.    register int        c,
  165.             count,
  166.             intersection,
  167.             setid = m_setid(),
  168.             x,
  169.             y, nexty;
  170.  
  171.    while( (count = get_all(coords)) == 0 )
  172.     ;
  173.    dprintf(stderr,"found %d windows\n", count);
  174.  
  175.    /*    Find the best spot.  We want to avoid too exhaustive a search.
  176.     We march through the screen, trying to fit the moving window into
  177.     spaces.  Any time we collide with a window, we skip to the right edge
  178.     of that window and note if it's top edge is the lowest one we've seen
  179.     which is still above where we are.  This allows us to skip over the
  180.     larger areas of occupied screen quickly.
  181.    */
  182.    for( y = ymax-high;  y >= 0;  y = nexty - 1 ) {
  183.       nexty = y;
  184.       for( x = xmax-wide;  x >= 0;  x -= 1 ) {
  185.      intersection = 0;
  186.      for( c = 0;  c < count;  c++ ) {
  187.         if( coords[c].setid == setid )
  188.            continue;
  189.             if( in_win( coords+c, x, y, x + wide, y + high ) ) {
  190.            intersection = 1;
  191.            nexty = Max( y, Max( nexty, coords[c].y - high ) );
  192.            x = coords[c].x - wide;
  193.            break;
  194.            }
  195.         }
  196.      if( !intersection ) {
  197.             dprintf(stderr,"going to %d, %d\n", x, y);
  198.         m_push(P_EVENT);
  199.         m_movewindow( x + XSLOP/2, y + YSLOP/2 );
  200.         m_pop();
  201.         return( 1 );
  202.         }
  203.      }
  204.       }
  205.    dprintf(stderr,"no openings\n");
  206.    return( 0 );
  207.    }
  208.  
  209.  
  210. /* check for window-rectangle intersection */
  211.  
  212. static
  213. int
  214. in_win(list,x0,y0,x1,y1)
  215. register struct window_data *list;        /* window coordinates */
  216. register int x0,y0,x1,y1;            /* rectangle coordinates */
  217.    {
  218.    return(
  219.    (
  220.       list->x + list->w < x0  ||  x1 < list->x  ||
  221.       list->y + list->h < y0  ||  y1 < list->y
  222.    ) ?  0  :  1);
  223.    }
  224.  
  225.  
  226. /* send an alarm signal */
  227.  
  228. static
  229. sigalrm()
  230.    {
  231.    m_sendme(Covered);
  232.    }
  233.  
  234.  
  235. static
  236. int
  237. m_setid()
  238. {
  239.     static int        setid = -1;
  240.     struct window_data    window;
  241.  
  242.     if( setid == -1 ) {
  243.         while( get_eachclientwin( &window ) )
  244.             ;
  245.         setid = window.setid;
  246.     }
  247.     return setid;
  248. }
  249.  
  250.  
  251. static
  252. usage( pgm )
  253. char    *pgm;
  254. {
  255.     fprintf( stderr, "Usage:  %s [ message [ fontnumber ] ]\n", pgm );
  256.     fputs( "\
  257. If the message is zero-length, the default message is printed.\n\
  258. If fontnumber is non-numberic or not available, zero is assumed.\n\
  259. ", stderr );
  260.     exit( 255 );
  261. }
  262.  
  263.  
  264. static
  265. setupwindow( text )
  266. char    *text;
  267. {
  268.     /* change window size */
  269.  
  270.     m_size(Max(strlen(text)-1, 5), 1);
  271.     m_setmode(M_NOWRAP);
  272.     m_printstr(text);
  273.  
  274.     /* how big is it */
  275.  
  276.     get_size(0, 0, &wide, &high);
  277.     get_param(0, &xmax, &ymax, &border);
  278.     wide += 2*border+XSLOP;
  279.     high += 2*border+YSLOP;
  280. }
  281.